package com.atelier.plugin.provider

import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo
import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder
import com.intellij.icons.AllIcons
import com.intellij.ide.util.DefaultPsiElementCellRenderer
import com.intellij.json.psi.JsonProperty
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.search.FilenameIndex
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.xml.XmlFile
//import com.intellij.sql.formatter.findSubSequence
import javax.swing.Icon

class MyBatisXMLNavigationProvider: RelatedItemLineMarkerProvider()
{
    override fun collectNavigationMarkers(
        element: PsiElement, result: MutableCollection<in RelatedItemLineMarkerInfo<*>>
                                         )
    {
        if (element !is XmlFile) {
            return
        }
        val xmlfile: XmlFile = element
        val tag = xmlfile.rootTag
        val xmlFileName = xmlfile.name
        val className = xmlFileName.substringBeforeLast(".xml")
        if (xmlfile.containingFile.virtualFile == null) {
            return
        }
        val targets: ArrayList<PsiElement> = ArrayList()
        // 1. 查找与 class 类名同名的 java 文件, 并追加到结果集合
        val psiClasses = FilenameIndex.getFilesByName(
            xmlfile.project, "$className.java", GlobalSearchScope.projectScope(xmlfile.project)
                                                   ).toList()
        /** 构建样式 */
        val builder: NavigationGutterIconBuilder<PsiElement> =
            NavigationGutterIconBuilder.create(AllIcons.FileTypes.Java).setTargets(targets)
                .setTooltipText("Navigate to Java resource").setAlignment(GutterIconRenderer.Alignment.RIGHT)
                .setCellRenderer(MyJAVACellRenderer())
        //构建根标签
        for (psiClass in psiClasses)
        {
            if (psiClass is PsiJavaFile){
                var javaFile: PsiJavaFile=psiClass
                val javaClasses = javaFile.classes
                val javaClass = javaClasses[0]
                if (javaClass.qualifiedName!! == tag!!.getAttributeValue("namespace"))
                {
                    targets.add(javaClass)
                    result.add(builder.createLineMarkerInfo(tag))
                }
            }
        }
        val subTags = tag!!.subTags

        if (targets.isEmpty()){
            println("未匹配到对应Java实体类")
            return
        }
        for (subTag in subTags)
        {
                val methodTargets: ArrayList<PsiElement> = ArrayList()
                val psiElement = targets[0]
                if (psiElement is PsiClass)
                {
                var psiClass: PsiClass = psiElement
                    val idAttribute = subTag.getAttributeValue("id")
                    val methods = psiClass.findMethodsByName(idAttribute,false)
                    for (method in methods)
                    {
                        methodTargets.add(method)
                    }
                    if(!methods.isEmpty())
                    {
                        val tagBuilder: NavigationGutterIconBuilder<PsiElement> =
                            NavigationGutterIconBuilder.create(AllIcons.FileTypes.Java).setTargets(methodTargets)
                                .setTooltipText("Navigate to Java resource")
                                .setAlignment(GutterIconRenderer.Alignment.RIGHT).setCellRenderer(MyJAVACellRenderer())
                        result.add(tagBuilder.createLineMarkerInfo(subTag!!))
                    }
                }
            }

    }
    class MyJAVACellRenderer : DefaultPsiElementCellRenderer()
    {
        override fun getElementText(element: PsiElement): String
        {
            val prefix = StringBuilder()
            if (element is JsonProperty)
            {
                prefix.append("Found Java! ")
            }
            return prefix.append(super.getElementText(element)).toString()
        }

        override fun getIcon(element: PsiElement): Icon
        {
            return AllIcons.FileTypes.Java
        }
    }
}